﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.UI;
using Newtonsoft.Json;
using System.Drawing;
using System.Drawing.Drawing2D;
using CSP.Common.Factories;
using System.Security.Cryptography;
using CSP.Common.Enum;
using CSP.Common.Providers;
using System.Net;
using System.IO;

namespace CSP.Common.Tools
{
    /// <summary>
    /// 工具箱
    /// </summary>
    public class CommonTool
    {

        private const string _keyPrefix = "checkimg_";
        /// <summary>
        /// 判断IP地址
        /// </summary>
        /// <param name="ip"></param>
        /// <returns></returns>
        public static bool CheckIPAndPort(string ip)
        {
            if (!Regex.IsMatch(ip, @"(?:25[0-5]|2[0-4]\d|1\d{0,2}|[1-9]\d?)\.(?:(?:25[0-5]|2[0-4]\d|1\d{0,2}|\d{1,2})\.){2}(?:25[0-5]|2[0-4]\d|1\d{0,2}|\d{1,2})"))
            {
                return false;

            }
            return true;
        }

        /// <summary>
        /// 将时间戳格式转化为DateTime格式
        /// </summary>
        /// <param name="timeSpan"></param>
        /// <returns></returns>
        public static DateTime ConvertToDateTime(double timeSpan)
        {
            return new DateTime(1970, 1, 1, 0, 0, 0, 0).AddSeconds(timeSpan);
        }

        public static double ConvertToTimeSpan(DateTime time)
        {
            return (time - TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1))).TotalSeconds;
        }

        /// <summary>
        /// 获取QQ联系URL链接
        /// </summary>
        /// <param name="qq">qq号码</param>
        /// <returns></returns>
        public static string GetQQContactURL(string qq)
        {
            return "http://wpa.qq.com/msgrd?v=3&uin=" + qq + "&site=qq&menu=yes";
        }

        /// <summary>
        /// 获取QQ联系图片URL链接
        /// </summary>
        /// <param name="qq"></param>
        /// <returns></returns>
        public static string GetQQContactImgURL(string qq)
        {
            return "http://wpa.qq.com/pa?p=2:" + qq + ":41";
        }

        /// <summary>
        /// 获取淘宝联系URl链接
        /// </summary>
        /// <param name="wangwang"></param>
        /// <returns></returns>
        public static string GetTaoBaoContactURL(string wangwang)
        {
            return "http://www.taobao.com/webww/ww.php?ver=3&touid=" + HttpUtility.UrlEncode(wangwang) + "&siteid=cntaobao&status=1&charset=utf-8";
        }

        /// <summary>
        /// 获取阿里旺旺联系图片链接
        /// </summary>
        /// <param name="wangwang"></param>
        /// <returns></returns>
        public static string GetTaoBaoContactImgURL(string wangwang)
        {

            return "http://amos.alicdn.com/realonline.aw?v=2&uid=" + HttpUtility.UrlEncode(wangwang) + "&site=cntaobao&s=1&charset=utf-8";
        }

        /// <summary>
        /// 将对象 序列化成json
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static string SerializeObject(object obj)
        {
            return JsonConvert.SerializeObject(obj);
        }

        /// <summary>
        /// 根据请求的Url将请求道页面内容转化为字符串。Get
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        public static string MakeGetByUrl(string url)
        {
            WebRequest request = WebRequest.Create(url);
            request.Method = "get";
            //request.ContentType = "application/x-www-form-urlencoded";
            WebResponse response = request.GetResponse();
            Stream webstream = response.GetResponseStream();
            StreamReader reader = new StreamReader(webstream);
            string result = reader.ReadToEnd();


            return result;
        }

        /// <summary>
        /// post webRequest 请求
        /// </summary>
        /// <param name="url"></param>
        /// <param name="post_data"></param>
        /// <returns></returns>
        public static string MakePostByUrlAndPostData(string url, string postData)
        {
            HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
            request.Method = "POST";
            request.ServicePoint.Expect100Continue = false;
            request.KeepAlive = true;
            Encoding encode = Encoding.GetEncoding("utf-8");
            var postdata = postData;
            request.ContentType = "application/x-www-form-urlencoded";
            var bytes = encode.GetBytes(postdata);
            request.ContentLength = bytes.Length;
            string result = "";

            var stream = request.GetRequestStream();
            stream.Write(bytes, 0, bytes.Length);
            stream.Close();
            stream = null;
            var response = request.GetResponse();
            var resp = response.GetResponseStream();
            var reader = new StreamReader(resp);
            result = reader.ReadToEnd();
            resp.Close();
            resp = null;
            reader.Close();
            reader = null;
            return result;

        }



        /// <summary>
        /// 根据信誉得分获取服务等级
        /// </summary>
        /// <param name="score"></param>
        /// <returns></returns>
        public static string GetServiceCreditGradeByScore(int score)
        {
            if (score < 4)
            {
                return "";
            }
            //1颗心
            else if (score >= 4 && score <= 10)
            {
                return "b_red_1.gif";
            }

            //2颗心
            else if (score >= 11 && score <= 40)
            {
                return "b_red_2.gif";
            }

            //3颗心
            else if (score >= 41 && score <= 90)
            {
                return "b_red_3.gif";
            }

            //4颗心
            else if (score >= 91 && score <= 150)
            {
                return "b_red_4.gif";
            }

            //5颗心
            else if (score >= 151 && score <= 250)
            {
                return "b_red_5.gif";
            }

            //1颗钻
            else if (score >= 251 && score <= 500)
            {
                return "s_blue_1.gif";
            }

            //2颗钻
            else if (score >= 501 && score <= 1000)
            {
                return "s_blue_2.gif";
            }

            //3颗钻
            else if (score >= 1001 && score <= 2000)
            {
                return "s_blue_3.gif";
            }

            //4颗钻
            else if (score >= 2001 && score <= 5000)
            {
                return "s_blue_4.gif";
            }

            //5颗钻
            else if (score >= 5001 && score <= 10000)
            {
                return "s_blue_5.gif";
            }

            //1颗皇冠
            else if (score >= 10001 && score <= 20000)
            {
                return "s_cap_1.gif";
            }

            //2颗皇冠
            else if (score >= 20001 && score <= 50000)
            {
                return "s_cap_2.gif";
            }

            //3颗皇冠
            else if (score >= 50001 && score <= 100000)
            {
                return "s_cap_3.gif";
            }

            //4颗皇冠
            else if (score >= 100001 && score <= 200000)
            {
                return "s_cap_4.gif";
            }

            //5颗皇冠
            else if (score >= 200001)
            {
                return "s_cap_5.gif";
            }
            else { return ""; }
        }


        /// <summary>
        /// 根据信誉得分获取消费等级
        /// </summary>
        /// <param name="score"></param>
        /// <returns></returns>
        public static string GetConsumptionCreditGradeByScore(int score)
        {
            if (score < 4)
            {
                return "";
            }
            //1颗心
            else if (score >= 4 && score <= 10)
            {
                return "b_red_1.gif";
            }

            //2颗心
            else if (score >= 11 && score <= 40)
            {
                return "b_red_2.gif";
            }

            //3颗心
            else if (score >= 41 && score <= 90)
            {
                return "b_red_3.gif";
            }

            //4颗心
            else if (score >= 91 && score <= 150)
            {
                return "b_red_4.gif";
            }

            //5颗心
            else if (score >= 151 && score <= 250)
            {
                return "b_red_5.gif";
            }

            //1颗钻
            else if (score >= 251 && score <= 500)
            {
                return "s_blue_1.gif";
            }

            //2颗钻
            else if (score >= 501 && score <= 1000)
            {
                return "s_blue_2.gif";
            }

            //3颗钻
            else if (score >= 1001 && score <= 2000)
            {
                return "s_blue_3.gif";
            }

            //4颗钻
            else if (score >= 2001 && score <= 5000)
            {
                return "s_blue_4.gif";
            }

            //5颗钻
            else if (score >= 5001 && score <= 10000)
            {
                return "s_blue_5.gif";
            }

            //1颗皇冠
            else if (score >= 10001 && score <= 20000)
            {
                return "s_cap_1.gif";
            }

            //2颗皇冠
            else if (score >= 20001 && score <= 50000)
            {
                return "s_cap_2.gif";
            }

            //3颗皇冠
            else if (score >= 50001 && score <= 100000)
            {
                return "s_cap_3.gif";
            }

            //4颗皇冠
            else if (score >= 100001 && score <= 200000)
            {
                return "s_cap_4.gif";
            }

            //5颗皇冠
            else if (score >= 200001)
            {
                return "s_cap_5.gif";
            }
            else { return ""; }
        }


        /// <summary>
        /// 获取时间格式的GUID
        /// </summary>
        /// <returns></returns>
        public static string GetGUIDForDateTime()
        {
            return DateTime.Now.ToString("yyyyMMddHHmmssffffff");
        }

        /// <summary>
        /// 获取分配好的关键词parms[0]=全匹配  parms[1]=匹配分词第一项 parms[2]=匹配分词第二项
        /// </summary>
        /// <param name="keyWords"></param>
        /// <returns></returns>
        public static List<string> GetSegmentationTermsByKeyWords(string keyWords)
        {
            List<string> result = new List<string>();
            if (string.IsNullOrWhiteSpace(keyWords))
            {
                return result;
            }

            //原版
            result.Add(keyWords);
            int indexLast = keyWords.Trim().IndexOf(' ');
            if (indexLast != -1)
            {
                result.Add(keyWords.Substring(0, indexLast));
                result.Add(keyWords.Substring(indexLast));
            }
            else if (keyWords.Length >= 4)
            {
                result.Add(keyWords.Substring(0, keyWords.Length / 2));
                result.Add(keyWords.Substring(keyWords.Length / 2, keyWords.Length - (keyWords.Length / 2)));
            }
            else
            {
                result.Add("");
                result.Add("");
            }
            return result;
        }

        /// <summary>
        /// 随机生成字符串
        /// </summary>
        /// <param name="number">字符串长度</param>
        /// <returns></returns>
        public static string GenerateCode(int number)
        {
            string checkCode = string.Empty;
            string vChar = "0,1,2,3,4,5,6,7,8,9";
            string[] vcArray = vChar.Split(',');

            int temp = -1;//记录上次随机数值，尽量避免产生几个一样的随机数
            Random rand = new Random();
            for (int i = 1; i < number + 1; i++)
            {
                if (temp != -1)
                {
                    rand = new Random(i * temp * unchecked((int)DateTime.Now.Ticks));
                }
                int t = rand.Next(vcArray.Length);
                if (temp != -1 && temp == t)
                {
                    return GenerateCode(number);
                }
                temp = t;
                checkCode += vcArray[t];
            }
            return checkCode;
        }
        public static string GenerateNumberCode(int number)
        {
            string checkCode = string.Empty;
            string vChar = "0,1,2,3,4,5,6,7,8,9";
            string[] vcArray = vChar.Split(',');

            int temp = -1;//记录上次随机数值，尽量避免产生几个一样的随机数
            Random rand = new Random();
            for (int i = 1; i < number + 1; i++)
            {
                if (temp != -1)
                {
                    rand = new Random(i * temp * unchecked((int)DateTime.Now.Ticks));
                }
                int t = rand.Next(vcArray.Length);
                if (temp != -1 && temp == t)
                {
                    return GenerateCode(number);
                }
                temp = t;
                checkCode += vcArray[t];
            }
            return checkCode;
        }
        /// <summary>
        /// 生成验证码图片
        /// </summary>
        /// <param name="checkCode">随机字符串</param>
        private static byte[] CreateCheckImage(string checkCode)
        {
            System.IO.MemoryStream ms = new System.IO.MemoryStream();
            if (checkCode == null || checkCode.Trim() == string.Empty)
            {
                return ms.ToArray();
            }

            System.Drawing.Bitmap image = new System.Drawing.Bitmap((int)Math.Ceiling((checkCode.Length * 12.5)), 22);
            Graphics g = Graphics.FromImage(image);
            try
            {
                Random radom = new Random();
                g.Clear(Color.White);
                for (int i = 0; i < 2; i++)
                {
                    int x1 = radom.Next(image.Width);
                    int x2 = radom.Next(image.Width);
                    int y1 = radom.Next(image.Height);
                    int y2 = radom.Next(image.Height);
                    g.DrawLine(new Pen(Color.Black), x1, y1, x2, y2);
                }
                Font font = new Font("Arial", 12, (FontStyle.Bold | FontStyle.Italic));
                LinearGradientBrush brush = new LinearGradientBrush(new Rectangle(0, 0, image.Width, image.Height), Color.Blue, Color.DarkRed, 1.2f, true);
                g.DrawString(checkCode, font, brush, 2, 2);

                //画图片的前景噪音点
                for (int i = 0; i < 50; i++)
                {
                    int x = radom.Next(image.Width);
                    int y = radom.Next(image.Height);
                    image.SetPixel(x, y, Color.FromArgb(radom.Next()));
                }

                //画图片的边框线
                g.DrawRectangle(new Pen(Color.Silver), 0, 0, image.Width - 1, image.Height - 1);
                image.Save(ms, System.Drawing.Imaging.ImageFormat.Gif);
            }
            catch { }
            finally
            {
                g.Dispose();
                image.Dispose();
            }

            return ms.ToArray();
        }

        /// <summary>
        /// 此key一定要是全局唯一的,获取生成的图片
        /// </summary>
        /// <param name="key"></param>
        public static byte[] CreateValidationImageByKey(string key)
        {
            byte[] result = null;
            if (string.IsNullOrWhiteSpace(key))
            {
                return result;
            }

            key = _keyPrefix + key;
            string code = CSP.Common.Tools.CommonTool.GenerateCode(4);
            result = CSP.Common.Tools.CommonTool.CreateCheckImage(code);
            CSP.Common.ICacheProvider _cacheProvider = CachedProviderFactory.GetLocalCachedProvider();
            _cacheProvider.AddData(key, code, DateTime.Now.AddMinutes(5));

            return result;

        }

        /// <summary>
        /// 验证通过返回true,失败false
        /// </summary>
        /// <param name="key"></param>
        /// <param name="imgCode"></param>
        /// <returns></returns>
        public static bool CheckImageByKeyAndImgCode(string key, string imgCode)
        {
            CSP.Common.ICacheProvider _cacheProvider = CachedProviderFactory.GetLocalCachedProvider();
            key = _keyPrefix + key;
            string code = _cacheProvider.GetData<string>(key);
            if (string.IsNullOrWhiteSpace(code))
            {
                return false;
            }

            if (code.ToLower() != imgCode.ToLower())
            {
                return false;
            }
            else
            {
                return true;
            }
        }

        /// <summary>  
        /// 返回32位加密字符串(无中文问题)  
        /// </summary>  
        /// <param name="srcStr">被加密字符串</param>  
        /// <returns></returns>  
        public static string MD5(string srcStr)
        {
            //return  
            //    System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(srcStr, "MD5").ToLower();  
            //或者执行下面的代码  
            MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
            return
                BitConverter.ToString(
                     md5.ComputeHash(Encoding.UTF8.GetBytes(srcStr))
                 ).Replace("-", string.Empty).ToLower();
        }

        /// <summary>  
        /// 返回16位或者32位加密后的字符串(无中文问题)  
        /// </summary>  
        /// <param name="srcStr"></param>  
        /// <param name="length"></param>  
        /// <returns></returns>  
        public static string MD5(string srcStr, MD5Len length)
        {
            if (length == MD5Len.SHORT) //16位MD5加密（取32位加密的9~25字符）
            {
                return System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(srcStr, "MD5").ToLower().Substring(8, 16).ToLower();
            }
            if (length == MD5Len.NORMAL) //32位加密   
            {
                return System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(srcStr, "MD5").ToLower();
            }
            return "00000000000000000000000000000000";
        }

        /// <summary>
        /// 获取IP
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public static string GetIP()
        {
            string ip = System.Web.HttpContext.Current.Request.UserHostAddress;

            if (ip == "::1")
            {
                ip = "127.0.0.1";
            }
            return ip;
        }

        /// <summary>
        /// IP地址转换成Int数据
        /// </summary>
        /// <param name="ip"></param>
        /// <returns></returns>
        public static long IpToInt(string ip)
        {
            char[] dot = new char[] { '.' };
            string[] ipArr = ip.Split(dot);
            if (ipArr.Length == 3)
                ip = ip + ".0";
            ipArr = ip.Split(dot);
            long ip_Int = 0;
            long p1 = long.Parse(ipArr[0]) * 256 * 256 * 256;
            long p2 = long.Parse(ipArr[1]) * 256 * 256;
            long p3 = long.Parse(ipArr[2]) * 256;
            long p4 = long.Parse(ipArr[3]);
            ip_Int = p1 + p2 + p3 + p4;
            return ip_Int;
        }

        /// <summary>
        /// int转换成IP
        /// </summary>
        /// <param name="ip_Int"></param>
        /// <returns></returns>
        public static string IntToIP(long ip_Int)
        {
            long seg1 = (ip_Int & 0xff000000) >> 24;
            if (seg1 < 0)
                seg1 += 0x100;
            long seg2 = (ip_Int & 0x00ff0000) >> 16;
            if (seg2 < 0)
                seg2 += 0x100;
            long seg3 = (ip_Int & 0x0000ff00) >> 8;
            if (seg3 < 0)
                seg3 += 0x100;
            long seg4 = (ip_Int & 0x000000ff);
            if (seg4 < 0)
                seg4 += 0x100;
            string ip = seg1.ToString() + "." + seg2.ToString() + "." + seg3.ToString() + "." + seg4.ToString();
            return ip;
        }
        /// <summary>
        /// 根据第一字符串的字符得到其ASCII码
        /// </summary>
        /// <param name="character"></param>
        /// <returns></returns>
        public static int Asc(string character)
        {
            if (character.Length == 1)
            {
                System.Text.ASCIIEncoding asciiEncoding = new System.Text.ASCIIEncoding();
                int intAsciiCode = (int)asciiEncoding.GetBytes(character)[0];
                return (intAsciiCode);
            }
            else
            {
                throw new Exception("Character is not valid.");
            }
        }

        /// <summary>
        /// 将ASCII转换成字符串
        /// </summary>
        /// <param name="asciiCode"></param>
        /// <returns></returns>
        public static string Chr(int asciiCode)
        {
            if (asciiCode >= 0 && asciiCode <= 255)
            {
                System.Text.ASCIIEncoding asciiEncoding = new System.Text.ASCIIEncoding();
                byte[] byteArray = new byte[] { (byte)asciiCode };
                string strCharacter = asciiEncoding.GetString(byteArray);
                return (strCharacter);
            }
            else
            {
                throw new Exception("ASCII Code is not valid.");
            }
        }

        /// <summary>
        /// 使用 authcode 方法对字符串加密
        /// </summary>
        /// <param name="source">原始字符串</param>
        /// <param name="key">密钥</param>
        /// <param name="expiry">加密字串有效时间，单位是秒</param>
        /// <returns>加密结果</returns>
        public static string DiscuzAuthcodeEncode(string source, string key, int expiry)
        {
            return AuthCode.DiscuzAuthcodeEncode(source, key, expiry);

        }

        /// <summary>
        /// 使用 Discuz authcode 方法对字符串加密
        /// </summary>
        /// <param name="source">原始字符串</param>
        /// <param name="key">密钥</param>
        /// <returns>加密结果</returns>
        public static string DiscuzAuthcodeEncode(string source, string key)
        {
            return AuthCode.DiscuzAuthcodeEncode(source, key);

        }

        /// <summary>
        /// 使用 Discuz authcode 方法对字符串解密
        /// </summary>
        /// <param name="source">原始字符串</param>
        /// <param name="key">密钥</param>
        /// <returns>解密结果</returns>
        public static string DiscuzAuthcodeDecode(string source, string key)
        {
            return AuthCode.DiscuzAuthcodeDecode(source, key);
        }

        private const string chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";

        private static string ConvertToBase(int b10, int targetBase)
        {
            if (targetBase < 2) throw new ArgumentException("Target base must be greater than 2.", "targetBase");
            if (targetBase > 36) throw new ArgumentException("Target base must be less than 36.", "targetBase");

            if (targetBase == 10) return b10.ToString();

            StringBuilder result = new StringBuilder();

            while (b10 >= targetBase)
            {
                int mod = b10 % targetBase;
                result.Append(chars[mod]);
                b10 = b10 / targetBase;
            }

            result.Append(chars[b10]);

            return Reverse(result.ToString());
        }

        private static int ConvertFromBase(string bx, int fromBase)
        {
            if (fromBase < 2) throw new ArgumentException("Base must be greater than 2.", "fromBase");
            if (fromBase > 36) throw new ArgumentException("Base must be less than 36.", "fromBase");

            if (fromBase == 10) return int.Parse(bx);

            bx = Reverse(bx);
            int acc = 0;

            for (int i = 0; i < bx.Length; i++)
            {
                int charValue = chars.IndexOf(bx[i]);
                acc += (int)Math.Pow(fromBase, i) * charValue;
            }

            return acc;
        }

        public static string Reverse(string s)
        {
            char[] charArray = new char[s.Length];
            int len = s.Length - 1;
            for (int i = 0; i <= len; i++)
                charArray[i] = s[len - i];
            return new string(charArray);
        }

        /// <summary>
        /// 函数在任意进制之间转换数字。
        /// </summary>
        /// <param name="bx">原始值</param>
        /// <param name="fromBase">数字原来的进制</param>
        /// <param name="toBase">要转换的进制</param>
        /// <returns></returns>
        public static string ConvertFromBaseToBase(string bx, int fromBase, int toBase)
        {
            int b10 = ConvertFromBase(bx, fromBase);
            return ConvertToBase(b10, toBase);
        }

        /// <summary>
        /// 随机SaltKey
        /// </summary>
        /// <param name="length"></param>
        /// <param name="numeric"></param>
        /// <returns></returns>
        public static string RandomForSaltkey(int length, int numeric = 0)
        {
            string seed = ConvertFromBaseToBase(MD5(GenerateCode(8)), 16, numeric != 0 ? 10 : 35);

            seed = numeric > 0 ? (seed.Replace("0", "") + "012340567890") : (seed + "zZ" + seed.ToUpper());
            string hash = "";
            int max = seed.Length - 1;
            for (int i = 0; i < length; i++)
            {
                Random r = new Random();
                //r.Next(0, max);
                hash += seed[r.Next(0, max)];
            }
            return hash;
        }

        public static string RandomString(int lens)
        {
            char[] CharArray = {
                                   'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's'
                                   , 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K',
                                   'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '0', '1', '2'
                                   , '3', '4', '5', '6', '7', '8', '9'
                               };
            int clens = CharArray.Length;
            string sCode = "";
            Random random = new Random();
            for (int i = 0; i < lens; i++)
            {
                sCode += CharArray[random.Next(clens)];
            }
            return sCode;
        }

        /// <summary>
        /// 字符串部分加密从头开始
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string PartEncrypt(string str)
        {
            string result = "";
            int seed = str.Length / 2;
            for (int i = 0; i < str.Length; i++)
            {
                if (seed <= i)
                {
                    result += "*";
                }
                else
                {
                    result += str[i];
                }
            }
            return result;
        }
    }
}
